<?php

class Url {

	private $_urlSegments = array(
		'module' => 'index',
		'controller' => 'index',
		'action' => 'index',
		'args' => array()
	);
	
	private $_urlParts = array();
	private $_basedir;
	private $_url;

	public function __construct($customUrl=false, $basedir=false, $toSegments=true) {
		
		// Set a custom url?
		if ($customUrl) $this->setUrl($customUrl);
		
		// Set basedir
		if ($basedir) {
		
			$this->_setBasedir($basedir);
		} else {
			
			$this->_setBasedir(str_replace('index.php', '', trim($_SERVER['PHP_SELF'])));
		}
		
		// Start initializing process
		$this->_init($toSegments);
	}
	
	private function _init($toSegments=true) {
		
		// Set url if not yet set
		if (!$this->_url) {
			
			$tmpUrl = trim($_SERVER['REQUEST_URI']);
		
			// Strip of the request uri, if needed
			if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) {
				
				// Get the string length of query string
				$queryStringLength = 0 - (strlen($_SERVER['QUERY_STRING']) + 1);
				
				// Rip off the url string
				$tmpUrl = substr($tmpUrl, 0, $queryStringLength);
			}
			
			$this->setUrl($tmpUrl);
		}
		
		// Map to segments?
		if ($toSegments) {
		
			$this->_mapToSegments();
		}
	}
	
	private function _mapToSegments() {
	
		// Get the url parts
		$tmpUrlParts = $this->getUrlParts();
		
		// Loop through the url parts and set correct segments.
		// The following indexes are preserved
		// [0] - Module
		// [1] - Controller
		// [2] - Action
		// [3+]- Arguments
		while (($segment = array_shift($tmpUrlParts)) !== null) {
			
			// Get the index
			$i = (isset($i)) ? $i : 0;
			
			// Set default to index if segments is empty or
			// skip if empty argument
			if (empty($segment)) {
				
				// Just continue if module, controller and action
				// were already set
				if ($i > 2) continue;
				
				// Default to index
				$segment = 'index';
			}
			
			// Set correct segment
			switch ($i) {
				// Module
				case 0:
					$this->_urlSegments['module'] = trim($segment);
					break;
				
				// Controller
				case 1:
					$this->_urlSegments['controller'] = trim($segment);
					break;
				
				// Action
				case 2:
					$this->_urlSegments['action'] = trim($segment);
					break;
					
				// Arguments
				default:
					$this->_urlSegments['args'][] = trim($segment);
					break;
			}
			
			$i++;
		}
	}
	
	private function _setBasedir($basedir) {
	
		// Set correct slashes if not yet set
		if (substr($basedir, 0, 1) != '/') { $basedir = "/{$basedir}"; }
		if (substr($basedir, -1, 1) != '/') { $basedir = "{$basedir}/"; }
		
		// Set a correct basedir, starting and ending with a slash
		$this->_basedir = $basedir;
	}
	
	private function _getSegment($part) {
	
		if (isset($this->_urlSegments[$part])) {
		
			return $this->_urlSegments[$part];
		}
		
		return false;
	}
	
	public function getParam($key) {
	
		if (isset($_GET[$key])) return trim($_GET[$key]);
		
		return false;
	}
	
	public function getUrlParts() {
	
		if (empty($this->_urlParts) && isset($this->_url)) {
			
			// Convert the urlString to an array
			$this->_urlParts = explode('/', $this->_url);
		}
		
		return $this->_urlParts;
	}
	
	public function getUrl() {
		
		return $this->_url;
	}
	
	public function setUrl($url) {
		
		// Get the url parts, if available
		$urlString = trim($url);
		
		// Remove base dir, if needed
		if (isset($this->_basedir)) {
		
			$urlString = str_replace($this->_basedir, '', $urlString);
		}
		
		// Strip of any heading and trailing slashes
		$this->_url = trim($urlString, "/");
	}
	
	public function getModule() { return $this->_getSegment('module'); }
	public function getController() { return $this->_getSegment('controller'); }
	public function getAction() { return $this->_getSegment('action'); }
	public function getArgs() { return $this->_getSegment('args'); }
	
	public function getArg($index) {
		
		if (!($args = $this->getArgs())) return false;
		
		if (isset($args[$index])) return trim($args[$index]);
		
		return false;
	}

}